﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.IO;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Xml.Serialization;
using XYAC.Framework.WohuaMesExtend.IHI.Extensions;

namespace XYAC.Framework.WohuaMesExtend.IHI.ViewModels
{
    /// <summary>
    /// 系统配置
    /// </summary>
    public partial class SystemConfigViewModel : ViewModelBase
    {

        public SystemConfigViewModel(IOptionsMonitor<AppConfig> options, ILogger<SystemConfigViewModel> logger)
        {
            this.CurrentAppConfig = options;
            this.Logger = logger;
            this.IsUseCustomizePlanDate = this.CurrentAppConfig.CurrentValue.IsUseCustomizePlanDate;
            this.CustomizePlanDate = this.CurrentAppConfig.CurrentValue.CustomizePlanDate;

        }
        public IOptionsMonitor<AppConfig> CurrentAppConfig { get; }
        public ILogger<SystemConfigViewModel> Logger { get; }

        /// <summary>
        /// 自定义计划时间
        /// </summary>
        [ObservableProperty]
        private DateTimeOffset? _customizePlanDate;

        /// <summary>
        /// 开启自定义计划时间
        /// </summary>
        [ObservableProperty]
        private bool _isUseCustomizePlanDate;
        /// <summary>
        /// 自动启动状态
        /// </summary>
        [ObservableProperty]
        private Boolean _chkAutoStartIsChecked = AutoStartupHelper.IsAutoStartupEnabled();

        /// <summary>
        /// 用户点击修改自动启动行为
        /// </summary>
        [RelayCommand]
        public void UserChangedAppStartupSet()
        {
            if (!this.ChkAutoStartIsChecked)
            {
                AdminHelper.EnsureAdmin();
                // 当复选框被选中时，取消自动启动
                AutoStartupHelper.SetAutoStartup(false);
            }
            else
            {
                AdminHelper.EnsureAdmin();
                // 当复选框未选中时，启用自动启动
                AutoStartupHelper.SetAutoStartup(true);
            }
        }


        /// <summary>
        /// 修改自定义计划时间
        /// </summary>
        [RelayCommand]
        private void ChangeIsUseCustomizePlanDate()
        {
            try
            {
                this.CurrentAppConfig.CurrentValue.IsUseCustomizePlanDate = this.IsUseCustomizePlanDate;

                SaveNewJsonConfig();
                //SaveNewXmlConfig();
            }
            catch (Exception ex)
            {
                this.Logger.LogError("保存使用计划配置节点失败", ex);
            }
        }
        private void SaveNewJsonConfig()
        {
            try
            {
                const string configPath = "./Configs/";
                const string configFileName = "AppConfig.json";
                const string tempFileName = "AppConfig_temp.json";

                string configFullPath = Path.Combine(configPath, configFileName);
                string tempFullPath = Path.Combine(configPath, tempFileName);

                // 复制原始配置文件到临时文件
                File.Copy(configFullPath, tempFullPath, overwrite: true);
                var currentValue = this.CurrentAppConfig.CurrentValue.Clone();
                // 修改临时文件
                JsonObject appSetting;
                using (FileStream fs = new FileStream(tempFullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    appSetting = JsonNode.Parse(fs).AsObject();

                    // 将当前的 CurrentAppConfig 序列化为 JsonNode
                    JsonNode sourceJsonNode = JsonSerializer.SerializeToNode(currentValue);

                    // 替换 "AppConfig" 节点
                    appSetting["AppConfig"] = sourceJsonNode;

                    // 清空文件并重置位置
                    fs.SetLength(0);
                    fs.Position = 0;

                    var options = new JsonSerializerOptions
                    {
                        WriteIndented = true // 格式化输出
                    };
                    JsonSerializer.Serialize(fs, appSetting, options);
                }

                // 原子性地替换原始配置文件
                File.Replace(tempFullPath, configFullPath, null);
            }
            catch (Exception ex)
            {
                this.Logger.LogError("保存配置文件失败", ex);
            }
        }

        private void SaveNewXmlConfig()
        {
            try
            {
                const string configPath = "./Configs/";
                const string configFileName = "AppConfig.xml";
                const string tempFileName = "AppConfig_temp.xml";

                string configFullPath = Path.Combine(configPath, configFileName);
                string tempFullPath = Path.Combine(configPath, tempFileName);

                // Copy the original config file to temp file
                File.Copy(configFullPath, tempFullPath, overwrite: true);

                // Modify the temp file
                XmlSerializer serializer = new XmlSerializer(typeof(AppConfig));
                AppConfig appSetting;
                using (FileStream fs = new FileStream(tempFullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                {
                    // Deserialize the existing config
                    appSetting = (AppConfig)serializer.Deserialize(fs);//exception

                    // Update the AppConfig property with the current configuration
                    appSetting = this.CurrentAppConfig.CurrentValue;

                    // Clear the file and reset position
                    fs.SetLength(0);
                    fs.Position = 0;

                    // Serialize the updated object back to the file
                    serializer.Serialize(fs, appSetting);
                }

                // Atomically replace the original config file
                File.Replace(tempFullPath, configFullPath, null);
            }
            catch (Exception ex)
            {
                this.Logger.LogError("保存配置文件失败", ex);
            }
        }


        /// <summary>
        /// 更新配置计划日期
        /// </summary>
        internal void UpdateCustomizePlanDateWithConfig(DateTimeOffset? newDate)
        {
            try
            {
                if (newDate.HasValue)
                    this.CurrentAppConfig.CurrentValue.CustomizePlanDate = newDate.Value.DateTime;

                SaveNewJsonConfig();
                //SaveNewXmlConfig();
            }
            catch (Exception ex)
            {
                this.Logger.LogError("保存配置计划日期失败", ex);
            }
        }
    }
}
